package pwd.allen.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import pwd.allen.service.IHelloService;

/**
 *
 * 引入消费者方式
 *      1）@Reference
 *      2）@Autowired：需要配置相应的ReferenceBean注入spring容器
 *
 * @Reference的loadbalance可以修改负载均衡策略
 *      random：RandomLoadBalance
 *      leastactive：LeastActiveLoadBalance
 *      roundrobin：RoundRobinLoadBalance
 *      consistenthash：ConsistentHashLoadBalance
 *
 * 降级
 *      屏蔽：不消费服务，直接返回
 *      容错：消费服务，错误时直接返回
 *
 * @author lenovo
 * @create 2019-10-06 9:35
 **/
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@RestController
public class HelloController {

    private static Logger logger = LoggerFactory.getLogger(HelloController.class);


//    @Reference(url = "127.0.0.1:20880")    //url：dubbo直连的方式
//    @DubboReference(version = "pwd-1.0", loadbalance = "random", timeout = 1000, stub="pwd.allen.service.stub.HelloServiceStub")
    @Autowired  //用ReferenceBean配置的消费者可以用Autowired注入
    private IHelloService helloService;

    /**
     * @param name
     * @return
     */
    @HystrixCommand(fallbackMethod = "mySayHello", commandProperties = @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000" ))
    @GetMapping("/sayHello/{name}")
    public Object sayHello(@PathVariable String name) {
        return helloService.sayHello(name);
    }

    /**
     * 测试结果：dubbo服务超时（reference-method > service-method > reference > service > consumer > provider） 或者 hystrix超时（超时会有异常：HystrixTimeoutException）
     * @param name
     * @param e
     * @return
     */
    public String mySayHello(String name, Throwable e) {
        logger.error(e.toString(), e);
        return String.format("this is hystrixCommand's fallbackMethod! name=%s, error=%s", name, e.toString());
    }

}
